package util

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"time"
)

// PostRequest 发送通用的 POST 请求
// url: 请求的目标地址
// requestData: 请求的 body 数据，可以是任何类型
// responseData: 用于存储响应数据的指针，必须传入一个指针，接收返回的数据
func PostRequest(url string, requestData interface{}, responseData interface{}) error {
	// 将请求数据序列化为 JSON
	requestBody, err := json.Marshal(requestData)
	if err != nil {
		return fmt.Errorf("error marshalling request data: %v", err)
	}

	// 创建一个新的 HTTP 请求
	req, err := http.NewRequest("POST", url, bytes.NewBuffer(requestBody))
	if err != nil {
		return fmt.Errorf("error creating new request: %v", err)
	}

	// 设置请求头
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Accept", "application/json")

	// 使用 http.Client 发送请求
	client := &http.Client{
		Timeout: 10 * time.Second, // 设置请求超时
	}
	resp, err := client.Do(req)
	if err != nil {
		return fmt.Errorf("error making POST request: %v", err)
	}
	defer resp.Body.Close()

	// 检查响应状态码
	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("request failed with status: %s", resp.Status)
	}

	// 读取响应体
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return fmt.Errorf("error reading response body: %v", err)
	}

	// 反序列化响应数据到传入的 responseData
	if err := json.Unmarshal(body, responseData); err != nil {
		return fmt.Errorf("error unmarshalling response data: %v", err)
	}

	return nil
}

// PostRequest 是一个通用的 POST 请求函数
// url: 请求的目标 URL
// postData: 请求体数据，可以是任意类型的字节数据（如 []byte 或 JSON 字符串）
// headers: 可选的自定义请求头
// 返回响应的状态和响应体内容（字节数据）
func PostRequestRaw(url string, postData []byte, headers map[string]string) (string, string, error) {
	// 创建 POST 请求
	req, err := http.NewRequest("POST", url, bytes.NewBuffer(postData))
	if err != nil {
		return "", "", fmt.Errorf("Error creating request: %v", err)
	}

	// 设置请求头
	for key, value := range headers {
		req.Header.Set(key, value)
	}

	// 发起请求并获取响应
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return "", "", fmt.Errorf("Error sending request: %v", err)
	}
	defer resp.Body.Close()

	// 读取响应内容
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", "", fmt.Errorf("Error reading response body: %v", err)
	}

	// 返回响应状态和响应体内容
	return resp.Status, string(body), nil
}
